<?php

namespace app\controller\admin\module\admin;

use think\exception\ValidateException;
use think\response\Json;
use think\response\View;

/**
 * @auth-name 管理员中心
 * @auth-alias admin
 */
class Index extends \app\controller\admin\module\AdminBaseController
{
    protected string $modelName = 'admin';

    protected function initialize()
    {
        parent::initialize();
        components\Account::getInstance()->setConfig($this->admin);
    }

    /**
     * @auth-name 主页
     * @auth-alias index
     * @return View
     */
    public function index(): View
    {
        $gadmin = Model('gadmin')->getList(['status' => 1], 'id, name');
        !empty($gadmin) and $gadmin = array_column($gadmin, 'name', 'id');
        return fetch('/admin/admin/index', [
            'gadmin' => $gadmin,
        ]);
    }

    /**
     * @auth-name 列表
     * @auth-alias list
     * @return Json
     */
    public function list(): Json
    {
        $limit = values('limit', 10);
        $condition = [];
        $keywordsField = values('keywords_field');
        $keywordsValues = values('keywords_values');
        (!empty($keywordsField) and !empty($keywordsValues)) and $condition[$keywordsField] = $keywordsValues;
        return json($this->model->getPageList($condition, 'id, name, gid, is_super, status, login_num, addtime', 'addtime desc', ['start' => ((values('page', 10) - 1) * $limit), 'limit' => $limit]));
    }

    /**
     * @auth-name 添加页面
     * @auth-alias add
     * @return View
     */
    public function add(): View
    {
        $gadmin = Model('gadmin')->getList(['status' => 1], 'id, name');
        return fetch('/admin/admin/add', [
            'gadmin' => $gadmin,
        ]);
    }

    /**
     * @auth-name 添加提交
     * @auth-alias add
     * @auth-request-method post
     * @return Json
     */
    public function addPost(): Json
    {
        $name = values('post.name');   //管理员名称
        $password = values('post.password');   //密码
        $repassword = values('post.repassword');   //密码
        $gid = values('post.gid', 0);  //角色ID
        $status = values('post.status', 2);    //是否开启
        try {
            $this->validate([
                'name' => $name,
                'password' => $password,
                'repassword' => $repassword,
                'gid' => $gid,
                'status' => $status,
            ],[
                'name|管理员名称' => ['require'],
                'password|密码' => ['require'],
                'repassword|确认密码' => ['require', 'confirm:password'],
                'gid|角色' => ['require'],
                'status|启用' => ['require'],
            ], ['repassword.confirm' => '两次密码不一致' ]);
            $repeat = $this->model->getInfo(['name' => $name], 'id');
            if(!empty($repeat)){
                return responseMsg('管理员名称已经存在');
            }
            $salt = randomSalt(22);
            $lastId = $this->model->add([
                'name' => $name,
                'salt' => $salt,
                'pwd' => password_hash(sha1($salt . $password), PASSWORD_BCRYPT, ['cost' => 12,]),
                'gid' => $gid,
                'status' => $status,
                'addtime' => time(),
            ], true);
            if($lastId > 0){
                putAdminLog("新增管理员[$lastId]");
                return responseMsg('新增成功', 200);
            }
            return responseMsg('新增失败');
        }catch (ValidateException $e){
            return responseMsg($e->getError());
        }
    }

    /**
     * @auth-name 编辑页面
     * @auth-alias edit
     * @return View
     */
    public function edit(): View
    {
        $id = values('get.id', 0);
        empty($id) and missPage();
        $info = $this->model->getInfo(['id' => $id], 'id, name, gid, status');
        empty($info) and errorData();
        $gadmin = Model('gadmin')->getList(['status' => 1], 'id, name');
        return fetch('/admin/admin/edit', [
            'info' => $info,
            'gadmin' => $gadmin,
        ]);
    }

    /**
     * @auth-name 编辑提交
     * @auth-alias edit
     * @auth-request-method post
     * @return Json
     */
    public function editPost(): Json
    {
        $id = values('post.id', 0);
        if(empty($id)){
            return responseMsg('缺少必要参数，请重新进入编辑页面');
        }
        $info = $this->model->getInfo(['id' => $id], 'id, salt, pwd');
        if(empty($info)){
            return responseMsg('未找到管理员信息');
        };
        $name = values('post.name');   //管理员名称
        $oldpassword = values('post.oldpassword');   //密码
        $password = values('post.password');   //密码
        $repassword = values('post.repassword');   //密码
        $gid = values('post.gid', 0);  //角色ID
        $status = values('post.status', 2);    //是否开启
        try {
            $this->validate([
                'name' => $name,
                'gid' => $gid,
                'status' => $status,
            ],[
                'name|管理员名称' => ['require'],
                'gid|角色' => ['require'],
                'status|启用' => ['require'],
            ]);
            $repeat = $this->model->getInfo([
                ['name', '=', $name],
                ['id', '<>', $id],
            ], 'id');
            if(!empty($repeat)){
                throw new ValidateException('管理员名称已经存在');
            }
            $data = [
                'name' => $name,
                'gid' => $gid,
                'status' => $status,
                'addtime' => time(),
            ];
            $verifyResult = $this->verifyPassword($oldpassword, $password, $repassword, $info);
            if($verifyResult['code'] != 200){
                throw new ValidateException($verifyResult['msg']);
            }
            $data = array_merge($data, $verifyResult['data']);
            if($this->model->edit(['id' => $id], $data)){
                putAdminLog("编辑管理员[$id]");
                return responseMsg('编辑成功', 200);
            }
            return responseMsg('编辑失败');
        }catch (ValidateException $e){
            return responseMsg($e->getError());
        }
    }

    /**
     * @auth-name 删除
     * @auth-alias del
     * @auth-request-method delete
     * @return Json
     */
    public function del(): Json
    {
        $idx = values('idx', []);
        if(!empty($idx)){
            $list = $this->model->getList(['id' => $idx]);
            if(empty($list)){
                return responseMsg('未找到管理员信息');
            }
            if($this->model->del(['id' => $idx])){
                putAdminLog("删除管理员[" . json_encode($list) . "]");
                return responseMsg('操作成功', 200);
            }
        }
        return responseMsg('操作失败，请稍后重试');
    }

    /**
     * @auth-name 状态修改
     * @auth-alias state
     * @auth-request-method post
     * @return Json
     */
    public function state(): Json
    {
        $idx = values('idx', []);
        $status = values('status', 1);
        if(!empty($idx)){
            $res = $this->model->edit(['id' => $idx], ['status' => $status]);
            if($res){
                putAdminLog("修改管理员信息[" . json_encode($idx) . "]");
                return responseMsg('操作成功', 200);
            }
        }
        return responseMsg('操作失败，请稍后重试');

    }

    /**
     * @auth-name 账号中心
     * @auth-alias center
     * @return View
     */
    public function center(): View
    {
        return fetch('/admin/admin/center');
    }

    /**
     * @auth-name 账号信息
     * @auth-alias account
     * @return View
     */
    public function account(): View
    {
        return fetch('/admin/admin/account');
    }

    /**
     * @auth-name 更新账号信息提交
     * @auth-alias account
     * @auth-request-method post
     * @return Json
     */
    public function updateAccountInfo(): Json
    {
        $res = components\Account::getInstance()->account();
        $res['code'] == 200 and $this->updateLoginData($this->admin['id'], 'avatar, nick');
        return responseMsg($res['msg'], $res['code']);
    }

    /**
     * @auth-name 修改密码
     * @auth-alias password
     * @return View
     */
    public function password(): View
    {
        return fetch('/admin/admin/password');
    }

    /**
     * @auth-name 修改密码提交
     * @auth-alias password
     * @auth-request-method post
     * @return Json
     */
    public function updatePassword(): Json
    {
        $res = components\Account::getInstance()->password();
        return $res['code'] == 1001 ? loginFailure($res['msg']) : responseMsg($res['msg'], $res['code']);
    }

    /**
     * @auth-name 邮箱页面
     * @auth-alias email
     * @return View
     */
    public function email(): View
    {
        return fetch('/admin/admin/email', [
            'countDown' => (time() - getCaches('email_code_countdown_' . $this->admin['token'], 0)) > 60 ? 0 : (60 - (time() - getCaches('email_code_countdown_' . $this->admin['token'], 0))),
//            'countDown' => 1,
        ]);
    }

    /**
     * 邮箱验证码
     * @auth-name 发送邮箱验证码
     * @auth-alias send
     * @auth-request-method post
     * @return Json
     */
    public function sendEmail(): Json
    {
        $countDownSec = (time() - getCaches('email_code_countdown_' . $this->admin['token'], 0)) > 60 ? 0 : (60 - (time() - getCaches('email_code_countdown_' . $this->admin['token'], 0)));
        if($countDownSec > 0){
            return responseMsg('请稍等' . $countDownSec . '秒后再发送');
        }
        $res = components\Account::getInstance()->sendEmail();
        return responseMsg($res['msg'], $res['code']);
    }

    /**
     * 绑定邮箱
     * @auth-name 绑定邮箱提交
     * @auth-alias bind
     * @auth-request-method post
     * @return Json
     */
    public function bindEmail(): Json
    {
        $res = components\Account::getInstance()->email();
        $res['code'] == 200 and $this->updateLoginData($this->admin['id'], 'email');
        return responseMsg($res['msg'], $res['code']);
    }

    /**
     * 核实密码
     * @param string $oldpassword
     * @param string $password
     * @param string $repassword
     * @param array $info
     * @return array
     */
    private function verifyPassword(string $oldpassword, string $password, string $repassword, array $info): array
    {
        try {
            $data = [];
            if(!empty($oldpassword) and !empty($password) and !empty($repassword)){
                if(!password_verify(sha1($info['salt'] . $oldpassword), $info['pwd'])){
                    throw new \Exception('原密码不正确');
                }
                if($password != $repassword){
                    throw new \Exception('两次密码不一致');
                }
                if($oldpassword == $password){
                    throw new \Exception('新密码不能与原密码一致');
                }
                $salt = randomSalt(22);
                $data['salt'] = $salt;
                $data['pwd'] = password_hash(sha1($salt . $password), PASSWORD_BCRYPT, ['cost' => 12,]);
            }else if(empty($oldpassword) and empty($password) and empty($repassword)){
            }else{
                throw new \Exception('请将旧密码、新密码、确认密码填写完整');
            }
            return responseArrayMsg('保存成功', 200, $data);
        }catch (\Exception $e){
            return responseArrayMsg($e->getMessage());
        }
    }
}